package com.cw.jeeyt.service.impl.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.cw.jeeyt.service.bo.system.SystemDictCacheBo;
import com.cw.jeeyt.dao.intf.system.SystemProjectInfoDao;
import com.cw.jeeyt.dao.model.system.SystemProjectInfoDo;
import com.cw.jeeyt.dao.query.system.SystemProjectInfoQuery;
import com.google.common.collect.Lists;
import com.cw.jeeyt.common.CommonUtil;
import com.cw.jeeyt.service.bo.system.SystemDataEntryBo;
import com.cw.jeeyt.service.bo.system.SystemDatabaseColumnBo;
import com.cw.jeeyt.service.bo.system.SystemDatabaseTableBo;
import com.cw.jeeyt.core.util.SessionUtil;
import com.cw.jeeyt.dao.intf.system.SystemDataEntryDao;
import com.cw.jeeyt.dao.model.system.SystemDataEntryDo;
import com.cw.jeeyt.service.converter.system.SystemDataEntryConverter;
import com.cw.jeeyt.service.intf.system.SystemDataEntryService;
import com.cw.jeeyt.service.intf.system.SystemDatabaseColumnService;
import com.cw.jeeyt.service.intf.system.SystemDatabaseTableService;
import com.cw.jeeyt.service.intf.system.SystemDictService;
import com.cw.jeeyt.service.utils.DataDicUtils;
import com.cw.lang.common.utils.CollectionUtil;
import com.cw.lang.mybatis.dto.PageInfo;
import com.cw.lang.common.utils.SequenceTool;

/**
 * 数据条目信息业务实现类
 *
 * @author chenw
 * @version 1.0.0
 */
@Service
public class SystemDataEntryServiceImpl implements SystemDataEntryService {

    private static final Logger logger = LoggerFactory.getLogger(SystemDataEntryServiceImpl.class);
    // 数据条目信息数据库操作接口
    @Autowired
    private SystemDataEntryDao systemDataEntryDao;
    @Autowired
    private SystemProjectInfoDao systemProjectInfoDao;
    //数据字典业务实现类
    @Autowired
    private SystemDictService systemDictService;
    @Autowired
    private SystemDatabaseColumnService systemDatabaseColumnService;
    @Autowired
    private SystemDatabaseTableService systemDatabaseTableService;

    /**
     * 新增SystemDataEntry
     *
     * @param systemDataEntryBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertSystemDataEntry(SystemDataEntryBo systemDataEntryBo) throws Exception {

        if (systemDataEntryBo == null) {
            logger.error("数据条目信息为空");
            return;
        }
        SystemDataEntryDo systemDataEntry = SystemDataEntryConverter.bo2Do(systemDataEntryBo);
        systemDataEntry.setDataJavaCode(CommonUtil.getFieldName(systemDataEntry.getDataCode()));
        systemDataEntry.setId(SequenceTool.nextLongId());
        systemDataEntry.setCreateBy(SessionUtil.getSessionUserId());// 创建人
        systemDataEntry.setCreateDate(new Date());// 创建时间
        systemDataEntry.setUpdateBy(SessionUtil.getSessionUserId());// 修改人
        systemDataEntry.setUpdateDate(new Date());// 修改时间
        systemDataEntryDao.insertSystemDataEntry(systemDataEntry);
    }

    /**
     * 更新SystemDataEntry信息
     *
     * @param systemDataEntryBo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSystemDataEntry(SystemDataEntryBo systemDataEntryBo) {

        if (systemDataEntryBo == null) {
            logger.error("数据条目信息为空");
            return;
        }
        SystemDataEntryDo systemDataEntry = SystemDataEntryConverter.bo2Do(systemDataEntryBo);
        systemDataEntry.setUpdateBy(SessionUtil.getSessionUserId());// 更新人
        systemDataEntry.setUpdateDate(new Date());
        systemDataEntryDao.updateSystemDataEntry(systemDataEntry);
    }

    /**
     * 删除SystemDataEntry
     *
     * @param systemDataEntryBo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteSystemDataEntry(SystemDataEntryBo systemDataEntryBo) throws Exception {
        if (systemDataEntryBo == null) {
            logger.error("数据条目信息为空");
            return;
        }
        systemDataEntryDao.deleteSystemDataEntry(SystemDataEntryConverter.bo2Do(systemDataEntryBo));

    }

    /**
     * 分页查询SystemDataEntry
     *
     * @param systemDataEntryBo
     * @param startNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<SystemDataEntryBo> queryByPage(SystemDataEntryBo systemDataEntryBo, Integer startNum,
        Integer pageSize) throws Exception {

        PageInfo<SystemDataEntryDo> pageInfo = systemDataEntryDao.queryByPage(
            SystemDataEntryConverter.bo2Do(systemDataEntryBo), startNum, pageSize);
        List<SystemDataEntryBo> systemDataEntryBos = SystemDataEntryConverter.doList2BoList(pageInfo.getList());
        if (CollectionUtil.isNotEmpty(systemDataEntryBos)) {
            Map<String, Object> dictMap = new HashMap<>();
            dictMap.put("dataType", "std_mysql_data_type");
            dictMap.put("dataJavaType", "std_data_java_type");
            JSONArray jsonArray = DataDicUtils.convertDict(JSON.parseArray(JSON.toJSONString(systemDataEntryBos)),
                dictMap);
            systemDataEntryBos = JSON.parseArray(jsonArray.toJSONString(), SystemDataEntryBo.class);
        }
        initProjectCode(systemDataEntryBos);
        return new PageInfo<>(pageInfo, systemDataEntryBos);
    }

    /**
     * 查询除了当前表模型中不存在的数据条目列表信息
     */
    @Override
    public PageInfo<SystemDataEntryBo> queryImportByPage(SystemDataEntryBo systemDataEntryBo, Integer startNum,
        Integer pageSize, String tableId) throws Exception {
        PageInfo<SystemDataEntryDo> pageInfo = systemDataEntryDao.queryImportByPage(
            SystemDataEntryConverter.bo2Do(systemDataEntryBo), startNum, pageSize, tableId);
        List<SystemDataEntryBo> systemDataEntryBos = SystemDataEntryConverter.doList2BoList(pageInfo.getList());
        if (CollectionUtil.isNotEmpty(systemDataEntryBos)) {
            Map<String, Object> dictMap = new HashMap<>();
            dictMap.put("dataType", "std_mysql_data_type");
            dictMap.put("dataJavaType", "std_data_java_type");
            JSONArray jsonArray = DataDicUtils.convertDict(JSON.parseArray(JSON.toJSONString(systemDataEntryBos)),
                dictMap);
            systemDataEntryBos = JSON.parseArray(jsonArray.toJSONString(), SystemDataEntryBo.class);
        }
        initProjectCode(systemDataEntryBos);
        return new PageInfo<>(pageInfo, systemDataEntryBos);
    }

    private void initProjectCode(List<SystemDataEntryBo> systemDataEntryBos) {
        if (CollectionUtil.isEmpty(systemDataEntryBos)) {
            return;
        }
        List<String> projectIds = systemDataEntryBos.stream()
            .map(dataEntry -> dataEntry.getProjectId())
            .collect(Collectors.toList());
        List<SystemProjectInfoDo> projectInfoDos = systemProjectInfoDao.selectByExample(SystemProjectInfoQuery.builder()
            .ids(projectIds)
            .build());
        systemDataEntryBos.forEach(input -> {
            try {
                SystemProjectInfoDo systemProjectInfoDo = projectInfoDos.stream()
                    .filter(projectInfoDo -> projectInfoDo.getId()
                        .equals(input.getProjectId()))
                    .findFirst()
                    .get();
                if (systemProjectInfoDo != null) {
                    input.setProjectCode(systemProjectInfoDo.getProjectCode());
                }
            } catch (Exception e) {
                logger.warn("找不到项目信息：{}",input.getProjectId());
            }
        });
    }

    /**
     * 根据主键查询SystemDataEntry信息
     *
     * @param id
     * @return
     */
    @Override
    public SystemDataEntryBo getSystemDataEntryById(String id) throws Exception {
        return SystemDataEntryConverter.do2Bo(systemDataEntryDao.getSystemDataEntryById(id));
    }

    /**
     * 根据数据条目编码、数据条目类型校验数据条目信息是否已经存在
     *
     * @param systemDataEntryBo 数据条目
     * @return
     * @throws Exception
     */
    @Override
    public boolean checkSystemDataEntry(SystemDataEntryBo systemDataEntryBo) throws Exception {
        SystemDataEntryDo sde = systemDataEntryDao.checkSystemDataEntry(
            SystemDataEntryConverter.bo2Do(systemDataEntryBo));
        if (sde != null) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 导入数据条目
     *
     * @param dataEntryStr 数据条目字符串
     * @param importType 导入方式
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importDataEntry(String dataEntryStr, String importType, String projectId) throws Exception {
        String[] dataEntryArray = dataEntryStr.split(",");
        if (dataEntryArray != null && dataEntryArray.length > 0) {
            for (String dataEntry : dataEntryArray) {
                SystemDataEntryDo systemDataEntry = new SystemDataEntryDo();
                String[] itemArray = dataEntry.split("#");
                String columnCode = itemArray[0];
                String columnName = itemArray[1];
                String columnType = itemArray[2];
                String columnLength = itemArray[3];
                String columnPoint = itemArray[4];
                systemDataEntry.setId(SequenceTool.nextLongId());
                systemDataEntry.setDataCode(columnCode);
                systemDataEntry.setDataName(columnName);
                systemDataEntry.setDataType(columnType);
                String javaType = CommonUtil.sqlType2JavaType(columnType);
                SystemDictCacheBo systemDictBo = systemDictService.getSystemDictByItemName("std_data_java_type",
                    javaType);
                if (systemDictBo != null) {
                    systemDataEntry.setDataJavaType(systemDictBo.getItemValue());
                }
                systemDataEntry.setDataJavaCode(CommonUtil.getFieldName(columnCode));
                systemDataEntry.setProjectId(projectId);
                systemDataEntry.setDataLength(columnLength);
                systemDataEntry.setDataPoint(columnPoint);
                systemDataEntry.setDataComment(columnName);
                systemDataEntry.setCreateBy(SessionUtil.getSessionUserId());// 创建人
                systemDataEntry.setCreateDate(new Date());// 创建时间
                systemDataEntry.setUpdateBy(SessionUtil.getSessionUserId());// 修改人
                systemDataEntry.setUpdateDate(new Date());// 修改时间
                SystemDataEntryDo sde = systemDataEntryDao.checkSystemDataEntry(systemDataEntry);
                if (sde == null) {
                    systemDataEntryDao.insertSystemDataEntry(systemDataEntry);
                }
            }
        }
    }

    /**
     * 批量新增数据条目信息
     */
    @Override
    public void insertSystemDataEntryBat(List<SystemDataEntryBo> systemDataEntryList) throws Exception {
        List<SystemDataEntryDo> dataEntryList = new ArrayList<SystemDataEntryDo>();
        for (SystemDataEntryBo systemDataEntry : systemDataEntryList) {
            SystemDataEntryDo sci = SystemDataEntryConverter.bo2Do(systemDataEntry);
            sci.setId(SequenceTool.nextLongId());
            dataEntryList.add(sci);
        }
        if (dataEntryList != null && !dataEntryList.isEmpty()) {
            systemDataEntryDao.insertSystemDataEntryBat(dataEntryList);
        }
    }

    @Override
    public PageInfo<SystemDataEntryBo> queryImportFacadeByPage(SystemDataEntryBo systemDataEntryBo, Integer startNum,
        Integer pageSize, Long objId) throws Exception {
        PageInfo<SystemDataEntryDo> pageInfo = systemDataEntryDao.queryImportFacadeByPage(
            SystemDataEntryConverter.bo2Do(systemDataEntryBo), startNum, pageSize, objId);
        List<SystemDataEntryBo> systemDataEntryBos = SystemDataEntryConverter.doList2BoList(pageInfo.getList());
        if (CollectionUtil.isNotEmpty(systemDataEntryBos)) {
            Map<String, Object> dictMap = new HashMap<>();
            dictMap.put("dataType", "std_mysql_data_type");
            dictMap.put("dataJavaType", "std_data_java_type");
            JSONArray jsonArray = DataDicUtils.convertDict(JSON.parseArray(JSON.toJSONString(systemDataEntryBos)),
                dictMap);
            systemDataEntryBos = JSON.parseArray(jsonArray.toJSONString(), SystemDataEntryBo.class);
        }
        return new PageInfo<>(pageInfo, systemDataEntryBos);
    }

    /**
     * 导入所有数据条目
     *
     * @param importType
     * @param projectId
     */
    @Override
    public void importAllDataEntry(String importType, String projectId) throws Exception {
        logger.info("导入所有数据条目信息");
        List<SystemDatabaseTableBo> systemDatabaseTableBos = systemDatabaseTableService.queryList();
        if (CollectionUtil.isEmpty(systemDatabaseTableBos)) {
            return;
        }
        for (SystemDatabaseTableBo systemDatabaseTableBo : systemDatabaseTableBos) {
            List<SystemDatabaseColumnBo> systemDatabaseColumnBos = systemDatabaseColumnService.queryColumnListByTableId(
                systemDatabaseTableBo.getId());
            List<SystemDataEntryDo> systemDataEntryModels = Lists.newArrayList();
            if (CollectionUtil.isNotEmpty(systemDatabaseColumnBos)) {
                for (SystemDatabaseColumnBo systemDatabaseColumnBo : systemDatabaseColumnBos) {
                    SystemDataEntryDo systemDataEntry = new SystemDataEntryDo();
                    String columnCode = systemDatabaseColumnBo.getColumnCode();
                    String columnName = systemDatabaseColumnBo.getColumnName();
                    String columnType = systemDatabaseColumnBo.getColumnType();
                    String columnLength = systemDatabaseColumnBo.getColumnLength();
                    String columnPoint = systemDatabaseColumnBo.getColumnPoint();
                    systemDataEntry.setId(SequenceTool.nextLongId());
                    systemDataEntry.setDataCode(columnCode);
                    systemDataEntry.setDataName(columnName);
                    systemDataEntry.setDataType(columnType);
                    logger.info("数据库字段编码:{},类型:{}", columnCode, columnType);
                    String javaType = CommonUtil.sqlType2JavaType(columnType);
                    SystemDictCacheBo systemDictBo = systemDictService.getSystemDictByItemName("std_data_java_type",
                        javaType);
                    if (systemDictBo != null) {
                        systemDataEntry.setDataJavaType(systemDictBo.getItemValue());
                    }
                    systemDataEntry.setDataJavaCode(CommonUtil.getFieldName(columnCode));
                    systemDataEntry.setProjectId(projectId);
                    systemDataEntry.setDataLength(columnLength);
                    systemDataEntry.setDataPoint(columnPoint);
                    systemDataEntry.setDataComment(columnName);
                    systemDataEntry.setCreateBy(SessionUtil.getSessionUserId());// 创建人
                    systemDataEntry.setCreateDate(new Date());// 创建时间
                    systemDataEntry.setUpdateBy(SessionUtil.getSessionUserId());// 修改人
                    systemDataEntry.setUpdateDate(new Date());// 修改时间
                    SystemDataEntryDo sde = systemDataEntryDao.checkSystemDataEntry(systemDataEntry);
                    if (sde == null) {
                        systemDataEntryModels.add(systemDataEntry);
                    }
                }
            }
            //批量新增
            if (CollectionUtil.isNotEmpty(systemDataEntryModels)) {
                systemDataEntryDao.insertSystemDataEntryBat(systemDataEntryModels);
            }
        }
    }
}
